//
//  NSOperatinViewController.m
//  iOSCodeLearning
//
//  Created by TFAppleWork-Summer on 2017/12/12.
//  Copyright © 2017年 Ace. All rights reserved.
//

#import "NSOperatinViewController.h"
#import "CustomOperation.h"


@interface NSOperatinViewController ()

@property(nonatomic,strong) NSOperationQueue *queue;

@end

@implementation NSOperatinViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"NSOperation";
    self.view.backgroundColor = [UIColor whiteColor];

    
    UIButton *stopBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    stopBtn.frame = CGRectMake(100, 100, 100, 50);
    stopBtn.backgroundColor = [UIColor orangeColor];
    [stopBtn setTitle:@"暂停" forState:UIControlStateNormal];
    [stopBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [stopBtn addTarget:self action:@selector(stopBtnClick:) forControlEvents:UIControlEventTouchUpInside];
   
    UIButton *cancleBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    cancleBtn.frame = CGRectMake(100, 200, 100, 50);
    cancleBtn.backgroundColor = [UIColor cyanColor];
    [cancleBtn setTitle:@"取消" forState:UIControlStateNormal];
    [cancleBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [cancleBtn addTarget:self action:@selector(cancleBtnClick:) forControlEvents:UIControlEventTouchUpInside];
    
    [self.view addSubview:stopBtn];
    [self.view addSubview:cancleBtn];
    
   
}
-(void)stopBtnClick:(UIButton *)button{
    //  不能暂停正在执行的任务 设置为yes 就会继续任务
    [self.queue setSuspended:YES];
    
}

- (void)cancleBtnClick:(UIButton *)button{
    
    // 取消之后是不可以恢复的，正在执行的不会取消
    [self.queue cancelAllOperations];
    
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
//    [self p_NSOperation];
//    [self p_NSInvocationOperaionWithQueue];
//    [self p_NSBlockOperationQueueWithQueue];
//    [self p_CustomOpearion];
//    [self p_OperationStatus];
//    [self p_OperationDependAndObserver];
//    [self p_NSOperationOneByOne];
    [self p_NSOperationOneByOne2];

    
}

/**
 一个接着一个
 */
-(void)p_NSOperationOneByOne{
    
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    
    for (NSInteger index = 0; index< 4 ;index ++ ) {
        NSBlockOperation *lastop;
        if ([queue operations].count > 0)
        {
            lastop = [[queue operations] lastObject];
        }
        
        
        NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
            
            for (NSInteger i = 0; i<30; i++) {
                NSLog(@"op%ld",index);
            }
        }];
        if (lastop) {
            [op1 addDependency:lastop];
        }
        [queue addOperation:op1];
    }
}

-(void)p_NSOperationOneByOne2{
     NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    queue.maxConcurrentOperationCount = 1;
    for (NSInteger index = 0; index< 4 ;index ++ ) {
        
        NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
            
            for (NSInteger i = 0; i<30; i++) {
                NSLog(@"op%ld",index);
            }
        }];
        
        [queue addOperation:op1];
    }
}

/**
 操作的依赖和监听
 */
-(void)p_OperationDependAndObserver{
    
    // 创建一个非主队列
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    NSOperationQueue *queue1 = [[NSOperationQueue alloc]init];
    // 封装操作
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"1~%@",[NSThread currentThread]);
    }] ;
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"2~%@",[NSThread currentThread]);
    }] ;

    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"3~%@",[NSThread currentThread]);
    }] ;

    
    NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"4~%@",[NSThread currentThread]);
    }] ;
    
    
    // 操作的监听
    op3.completionBlock = ^{
      // block中的代码并不会在op3所在的队列中执行，即op3执行结束以后
        NSLog(@"操作3 执行完毕%@",[NSThread currentThread]);
    };
    
    // op1 依赖于 op4 执行结束结束才能执行（下面同理）
    // 操作依赖之间不可以循环依赖
    [op1 addDependency:op4];
    [op4 addDependency:op3];
    [op3 addDependency:op2];

    [queue addOperation:op1];
    [queue addOperation:op2];
    [queue addOperation:op3];
    // 可以跨队列依赖
    [queue addOperation:op4];
    
    
    

}

/**
 NSOperation的状态
 */
- (void)p_OperationStatus{
    
    NSBlockOperation * op1 = [NSBlockOperation blockOperationWithBlock:^{
        for (NSInteger i = 0; i< 10000; i++) {
            NSLog(@"一 ---%ld----%@",i,[NSThread currentThread]);
        }
    }];
    
    NSBlockOperation * op2 = [NSBlockOperation blockOperationWithBlock:^{
        for (NSInteger i = 0; i< 10000; i++) {
            NSLog(@"二 ---%ld----%@",i,[NSThread currentThread]);
        }
    }];
    
    NSBlockOperation * op3 = [NSBlockOperation blockOperationWithBlock:^{
        for (NSInteger i = 0; i< 10000; i++) {
            NSLog(@"三 ---%ld----%@",i,[NSThread currentThread]);
        }
    }];
    
    NSBlockOperation * op4 = [NSBlockOperation blockOperationWithBlock:^{
        for (NSInteger i = 0; i< 10000; i++) {
            NSLog(@"四 ---%ld----%@",i,[NSThread currentThread]);
        }
    }];
    
    [self.queue addOperation:op1];
    [self.queue addOperation:op2];
    [self.queue addOperation:op3];
    [self.queue addOperation:op4];
}

/**
 自定义操作
 */
- (void)p_CustomOpearion{
    
    CustomOperation *customOp1 = [[CustomOperation alloc]init];
    CustomOperation *customOp2 = [[CustomOperation alloc]init];
    
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    
    [queue addOperation:customOp1];
    [queue addOperation:customOp2];
    
}

/**
 NSBlockOperation 与NSOperationQueue 的结合使用
 */
-(void)p_NSBlockOperationQueueWithQueue{
  
    // 1 通过block 封装任务
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"block 封装的任务1 %@ ",[NSThread currentThread]);
    }];
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"block 封装的任务2 %@", [NSThread currentThread]);
    }];
    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"block 封装的任务3 %@",[NSThread currentThread]);
    }];
    
    // ps :还可以在操作中
    [op1 addExecutionBlock:^{
        NSLog(@"op1 追加的任务 %@",[NSThread currentThread]);
    }];
    
    [op2 addExecutionBlock:^{
        NSLog(@"op2 追加的任务 %@",[NSThread currentThread]);
    }];
    [op3 addExecutionBlock:^{
        NSLog(@"op2 追加的任务 %@",[NSThread currentThread]);
    }];
    
    //2 创建操作队列将
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
   
    // 将操作添加到队列中 （内部已经调用了start 方法）
    [queue addOperation:op1];
    [queue addOperation:op2];
    [queue addOperation:op3];
    
 
    // ps ： 添加任务到队列中的简单方法
    [queue addOperationWithBlock:^{
        NSLog(@"添加任务到队列中的简单方法 %@",[NSThread currentThread]);
    }];
}


/**
 NSInvocationOperation与NSOperationQueue 的结合使用

 */
-(void)p_NSInvocationOperaionWithQueue{
    
    NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download1) object:nil];
    NSInvocationOperation *op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download2) object:nil];
    NSInvocationOperation *op3 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download3) object:nil];

    // 创建队列
    /*
     GCD：
     串行： create & 主队列
     并发： create & 全局并发队列
     
     NSOperation:
     主队列：  [NSOperationQueue mainQueue] 和GCD中的主队列一样，在主线程中执行
     非主队列：[[NSOperationQueue alloc] init] 比较特殊，同时具备串行和并发的功能
     */
    
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];//(非主队列)
    // 添加操作到队列中执行
    [queue addOperation:op1];
    [queue addOperation:op2];
    [queue addOperation:op3];
    
    
}

- (void)download1{
    NSLog(@"download1  %@",[NSThread currentThread]);
}
- (void)download2{
    NSLog(@"download2  %@",[NSThread currentThread]);
    
}
- (void)download3{
    NSLog(@"download3  %@",[NSThread currentThread]);
}




/**
 NSOperation 的简单使用
 */
-(void)p_NSOperation{
    // 1 创建操作
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"操作一 %@",[NSThread currentThread]);
    }];
    
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"操作二 %@",[NSThread currentThread]);
    }];
    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"操作三 %@",[NSThread currentThread]);
    }];

    /*
     2 追加任务
     2.1 如果一个操作中任务的数量>1 ,会才子线程，并发执行任务
     2.2 不过操作中追加的任务不一定在子线程中执行，有可能是主线程
     */
    
    [op3 addExecutionBlock:^{
        NSLog(@"追加任务 %@", [NSThread currentThread]);
    }];
    [op3 addExecutionBlock:^{
        NSLog(@"追加任务 %@", [NSThread currentThread]);
    }];
  
    [op3 addExecutionBlock:^{
        NSLog(@"追加任务 %@", [NSThread currentThread]);
    }];

    [op3 addExecutionBlock:^{
        NSLog(@"追加任务 %@", [NSThread currentThread]);
    }];

    [op3 addExecutionBlock:^{
        NSLog(@"追加任务 %@", [NSThread currentThread]);
    }];
    [op3 addExecutionBlock:^{
        NSLog(@"追加任务 %@", [NSThread currentThread]);
    }];
    [op3 addExecutionBlock:^{
        NSLog(@"追加任务 %@", [NSThread currentThread]);
    }];
    [op1 start];
    [op2 start];
    [op3 start];
}

-(NSOperationQueue *)queue{
    if (!_queue) {
        _queue = [[NSOperationQueue alloc]init];
        /*
         maxConcurrentOperationCount > 1 并发队列
         maxConcurrentOperationCount = 1 串行队列
         maxConcurrentOperationCount = 0 不执行任务
         maxConcurrentOperationCount = -1 特殊意义
         */
        _queue.maxConcurrentOperationCount = 1;
    }
    return _queue;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}


@end
